#ifdef _S_ETYPE
#ifdef _S_PREFIX

#ifndef _ERROR_ROUTINE
#warning _ERROR_ROUTINE not defined
#endif
#include <stdlib.h>

#define __cat(a, b) a ## b
#define _CAT(a, b) __cat(a, b)
#define _PREFIXED(a) _CAT(_S_PREFIX, a)
#define _STACK _PREFIXED(stack)
typedef struct
{
    _S_ETYPE *a;
    size_t top;
    size_t size;
}_STACK;

_STACK _PREFIXED(new)(size_t size)
{
    _STACK s;
    s.a = (_S_ETYPE*) malloc(size * sizeof(_S_ETYPE));
    s.top = 0;
    s.size = size;
    return s;
}

_S_ETYPE _PREFIXED(pop)(_STACK *s)
{
    if (s->top == 0){
#ifdef _ERROR_ROUTINE
        _ERROR_ROUTINE("Stack underflow\n");
#endif
        return;
    }
    return s->a[--s->top];
}

void _PREFIXED(push)(_STACK *s, _S_ETYPE e)
{
    if (s->top == s->size){
#ifdef _ERROR_ROUTINE
        _ERROR_ROUTINE("Stack overflow\n");
#endif
        return;
    }
    s->a[s->top++] = e;
}

void _PREFIXED(print)(_STACK s, char *fmt)
{
    int i;
    for (i = 0; i < s.top; i++){
        printf(fmt, s.a[i]);
    }
}

#undef __cat
#undef _CAT
#undef _PREFIXED
#undef _STACK

#undef _S_ETYPE
#undef _S_PREFIX

#else
#error _S_PREFIX not defined
#endif
#else
#error _S_ETYPE not defined
#endif
